﻿Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.EditorInput
Imports AcadEx = Autodesk.AutoCAD.Runtime.Exception

Public Class Create3dSolid

    Private db As Database

    Public Sub New()
        db = HostApplicationServices.WorkingDatabase
    End Sub

#Region "第二章第12节  创建三维实体"
    '创建长方体
    <CommandMethod("AddBox")> _
    Public Sub AddBox()
        Dim _solid As Solid3d = New Solid3d()
        _solid.CreateBox(40, 50, 30)
        Dim xform As Matrix3d
        Dim vec As Vector3d = New Vector3d(100, 100, 100)
        xform = Matrix3d.PlaneToWorld(vec)
        _solid.TransformBy(xform)
        CreateEnt.PostToModelSpace(_solid)
    End Sub

    '创建圆锥体
    <CommandMethod("AddCylinder")> _
    Public Sub AddCylinder()
        Dim _solid As Solid3d = New Solid3d()
        _solid.CreateFrustum(30, 10, 10, 0)
        CreateEnt.PostToModelSpace(_solid)
    End Sub

    '创建圆锥体
    <CommandMethod("AddSpire")> _
    Public Sub AddSpire()
        '指定创建螺旋线的参数
        '半径和每一周在垂直方向的增量
        Dim radius, deltaVertical As Double
        '螺旋线的旋转圈数和组成一圈的分段数
        Dim number, segment As Double

        radius = 30
        deltaVertical = 12
        number = 5
        segment = 30

        ' 计算点的个数和角度间隔 
        Dim n As Integer = CInt(number * segment) '点的个数实际上是n+1 
        Dim angle As Double = 8 * Math.Atan(1) / segment '两点之间的旋转角度 

        '计算控制点的坐标 
        Dim points As Point3dCollection = New Point3dCollection() ' 控制点坐标集合
        For i As Integer = 0 To n
            Dim vertex As Point3d
            Dim x As Double = radius * Math.Cos(8 * i * Math.Atan(1) / segment)
            Dim y As Double = radius * Math.Sin(8 * i * Math.Atan(1) / segment)
            Dim z As Double = i * deltaVertical / segment
            vertex = New Point3d(x, y, z)
            points.Add(vertex)
        Next

        '创建螺旋线路径
        Dim poly3d As Polyline3d = New Polyline3d(Poly3dType.SimplePoly, points, False)
        '将路径添加到模型空间 
        Dim spireId As ObjectId = CreateEnt.PostToModelSpace(poly3d)

        '创建一个圆作为拉伸的截面 

        Dim normal As Vector3d = Vector3d.YAxis '圆所在平面的法矢量 
        Dim ptCenter As Point3d = New Point3d(30, 0, 0) '圆心位置与半径的大小有关
        Dim _circle As Circle = New Circle(ptCenter, normal, 3)
        Dim circleId As ObjectId = CreateEnt.CreateCircle(ptCenter, normal, 3)

        '根据圆创建一个面域 
        Dim boundaryIds, regionIds As ObjectIdCollection
        boundaryIds = New ObjectIdCollection()
        boundaryIds.Add(circleId)
        regionIds = CreateEnt.CreateRegion(boundaryIds)

        '打开拉伸截面和拉伸路径
        Dim _solid As Solid3d
        Using trans As Transaction = db.TransactionManager.StartTransaction()
            Dim _region As Region = DirectCast(trans.GetObject(regionIds(0), OpenMode.ForRead, True), _
                                               Region)
            Dim _poly As Polyline3d = DirectCast(trans.GetObject(spireId, OpenMode.ForRead), _
                                                 Polyline3d)
            _solid = New Solid3d()
            '进行拉伸操作 
            _solid.ExtrudeAlongPath(_region, _poly, 0)
        End Using

        CreateEnt.PostToModelSpace(_solid)
    End Sub

    '旋转面域生成一个实体
    <CommandMethod("RevolveEnt")> _
    Public Sub RevolveEnt()
        '设置顶点的坐标 
        Dim points As Point3dCollection = New Point3dCollection()
        points.Add(New Point3d(15, 0, 0))
        points.Add(New Point3d(45, 0, 0))
        points.Add(New Point3d(35, 9, 0))
        points.Add(New Point3d(41, 18, 0))
        points.Add(New Point3d(15, 18, 0))
        '创建作为旋转截面的多段线 
        Dim poly As Polyline3d = New Polyline3d(Poly3dType.SimplePoly, points, True)
        Dim polyId As ObjectId = CreateEnt.PostToModelSpace(poly)
        '将闭合的多段线转化成面域
        Dim boundaryIds, regionIds As ObjectIdCollection
        boundaryIds = New ObjectIdCollection()
        boundaryIds.Add(polyId)
        regionIds = CreateEnt.CreateRegion(boundaryIds)


        Dim _solid As Solid3d
        Using trans As Transaction = db.TransactionManager.StartTransaction()
            Try
                Dim _region As Region = DirectCast(trans.GetObject(regionIds(0), OpenMode.ForRead, True), _
                                                   Region)

                _solid = New Solid3d()
                '进行拉伸操作 
                _solid.Revolve(_region, Point3d.Origin, Vector3d.YAxis, 8 * Math.Atan(1))
                CreateEnt.PostToModelSpace(_solid)
            Catch ex As AcadEx
                Util.Output(ex.Message)
            End Try


        End Using
    End Sub

    <CommandMethod("BooleanOperation")> _
    Public Sub BooleanOperation()
        '创建两个长方体 
        Dim solid1 As Solid3d = New Solid3d()
        solid1.CreateBox(40, 50, 30)
        Dim solid2 As Solid3d = New Solid3d()
        solid2.CreateBox(40, 50, 30)

        '使用几何变换矩阵移动长方体 
        Dim xform As Matrix3d = Matrix3d.PlaneToWorld(New Vector3d(20, 25, 15))
        solid1.TransformBy(xform)

        '将长方体添加到模型空间 
        Dim solidId1 As ObjectId = CreateEnt.PostToModelSpace(solid1)
        Dim solidId2 As ObjectId = CreateEnt.PostToModelSpace(solid2)


        Using trans As Transaction = db.TransactionManager.StartTransaction()
            Try
                solid1 = DirectCast(trans.GetObject(solidId1, OpenMode.ForWrite), _
                                    Solid3d)
                solid2 = DirectCast(trans.GetObject(solidId2, OpenMode.ForWrite), _
                                    Solid3d)


                '进行布尔运算，生成新的实体 
                solid1.BooleanOperation(BooleanOperationType.BoolUnite, solid2)
                '将其删除
                solid2.Erase()
            Catch ex As AcadEx
                Util.Output(ex.Message)
            Finally
                trans.Commit()
            End Try
        End Using
    End Sub
#End Region


End Class

